/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
 * Qwt Widget Library
 * Copyright (C) 1997   Josef Wilgen
 * Copyright (C) 2002   Uwe Rathmann
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the Qwt License, Version 1.0
 *****************************************************************************/

#include <qevent.h>
#include "qwt_event_pattern.h"
#include "qwt_picker_machine.h"

//! Constructor
QwtPickerMachine::QwtPickerMachine():
    d_state(0)
{
}

//! Destructor
QwtPickerMachine::~QwtPickerMachine()
{
}

//! Return the current state
int QwtPickerMachine::state() const
{
    return d_state;
}

//! Change the current state
void QwtPickerMachine::setState(int state)
{
    d_state = state;
}

//! Set the current state to 0.
void QwtPickerMachine::reset() 
{
    setState(0);
}

//! Transition
QwtPickerMachine::CommandList QwtPickerClickPointMachine::transition(
    const QwtEventPattern &eventPattern, const QEvent *e)
{   
    QwtPickerMachine::CommandList cmdList;

    switch(e->type())
    {
        case QEvent::MouseButtonPress:
        {
            if ( eventPattern.mouseMatch(
                QwtEventPattern::MouseSelect1, (const QMouseEvent *)e) )
            {
                cmdList += Begin;
                cmdList += Append;
                cmdList += End;
            }
            break;
        }
        case QEvent::KeyPress:
        {   
            if ( eventPattern.keyMatch(
                QwtEventPattern::KeySelect1, (const QKeyEvent *)e) )
            {
                cmdList += Begin;
                cmdList += Append;
                cmdList += End;
            }   
            break;
        }
        default:
            break;
    }

    return cmdList;
}

//! Transition
QwtPickerMachine::CommandList QwtPickerDragPointMachine::transition(
    const QwtEventPattern &eventPattern, const QEvent *e)
{   
    QwtPickerMachine::CommandList cmdList;

    switch(e->type())
    {
        case QEvent::MouseButtonPress:
        {
            if ( eventPattern.mouseMatch(
                QwtEventPattern::MouseSelect1, (const QMouseEvent *)e) )
            {
                if ( state() == 0 )
                {
                    cmdList += Begin;
                    cmdList += Append;
                    setState(1);
                }
            }
            break;
        }
        case QEvent::MouseMove:
        case QEvent::Wheel:
        {
            if ( state() != 0 )
                cmdList += Move;
            break;
        }
        case QEvent::MouseButtonRelease:
        {
            if ( state() != 0 )
            {
                cmdList += End;
                setState(0);
            }
            break;
        }
        case QEvent::KeyPress:
        {
            if ( eventPattern.keyMatch(
                QwtEventPattern::KeySelect1, (const QKeyEvent *)e) )
            {
                if ( state() == 0 )
                {
                    cmdList += Begin;
                    cmdList += Append;
                    setState(1);
                }
                else
                {
                    cmdList += End;
                    setState(0);
                }
            }
            break;
        }
        default:
            break;
    }

    return cmdList;
}

//! Transition
QwtPickerMachine::CommandList QwtPickerClickRectMachine::transition(
    const QwtEventPattern &eventPattern, const QEvent *e)
{   
    QwtPickerMachine::CommandList cmdList;

    switch(e->type())
    {
        case QEvent::MouseButtonPress:
        {
            if ( eventPattern.mouseMatch(
                QwtEventPattern::MouseSelect1, (const QMouseEvent *)e) )
            {
                switch(state())
                {
                    case 0:
                    {   
                        cmdList += Begin;
                        cmdList += Append;
                        setState(1);
                        break;
                    }
                    case 1:
                    {
                        // Uh, strange we missed the MouseButtonRelease
                        break; 
                    }
                    default:
                    {
                        cmdList += End;
                        setState(0);
                    }
                }
            }
        }
        case QEvent::MouseMove:
        case QEvent::Wheel:
        {
            if ( state() != 0 )
                cmdList += Move;
            break;
        }
        case QEvent::MouseButtonRelease:
        {
            if ( eventPattern.mouseMatch(
                QwtEventPattern::MouseSelect1, (const QMouseEvent *)e) )
            {
                if ( state() == 1 )
                {
                    cmdList += Append;
                    setState(2);
                }
            }
            break;
        }
        case QEvent::KeyPress:
        {   
            if ( eventPattern.keyMatch(
                QwtEventPattern::KeySelect1, (const QKeyEvent *)e) )
            {
                if ( state() == 0 )
                {
                    cmdList += Begin;
                    cmdList += Append;
                    setState(1);
                }
                else
                {
                    if ( state() == 1 )
                    {
                        cmdList += Append;
                        setState(2);
                    }
                    else if ( state() == 2 )
                    {
                        cmdList += End;
                        setState(0);
                    }
                }
            }   
            break;
        }
        default:
            break;
    }

    return cmdList;
}

//! Transition
QwtPickerMachine::CommandList QwtPickerDragRectMachine::transition(
    const QwtEventPattern &eventPattern, const QEvent *e)
{   
    QwtPickerMachine::CommandList cmdList;

    switch(e->type())
    {
        case QEvent::MouseButtonPress:
        {
            if ( eventPattern.mouseMatch(
                QwtEventPattern::MouseSelect1, (const QMouseEvent *)e) )
            {
                if ( state() == 0 )
                {
                    cmdList += Begin;
                    cmdList += Append;
                    cmdList += Append;
                    setState(2);
                }
            }
            break;
        }
        case QEvent::MouseMove:
        case QEvent::Wheel:
        {
            if ( state() != 0 )
                cmdList += Move;
            break;
        }
        case QEvent::MouseButtonRelease:
        {
            if ( state() == 2 )
            {
                cmdList += End;
                setState(0);
            }
            break;
        }
        case QEvent::KeyPress:
        {
            if ( eventPattern.keyMatch(
                QwtEventPattern::KeySelect1, (const QKeyEvent *)e) )
            {
                if ( state() == 0 )
                {
                    cmdList += Begin;
                    cmdList += Append;
                    cmdList += Append;
                    setState(2);
                }
                else
                {
                    cmdList += End;
                    setState(0);
                }
            }
            break;
        }
        default:
            break;
    }

    return cmdList;
}

//! Transition
QwtPickerMachine::CommandList QwtPickerPolygonMachine::transition(
    const QwtEventPattern &eventPattern, const QEvent *e)
{
    QwtPickerMachine::CommandList cmdList;

    switch(e->type())
    {
        case QEvent::MouseButtonPress:
        {
            if ( eventPattern.mouseMatch(
                QwtEventPattern::MouseSelect1, (const QMouseEvent *)e) )
            {
                if (state() == 0)
                {
                    cmdList += Begin;
                    cmdList += Append;
                    cmdList += Append;
                    setState(1);
                }
                else
                {
                    cmdList += End;
                    setState(0);
                }
            }
            if ( eventPattern.mouseMatch(
                QwtEventPattern::MouseSelect2, (const QMouseEvent *)e) )
            {
                if (state() == 1)
                    cmdList += Append;
            }
            break;
        }
        case QEvent::MouseMove:
        case QEvent::Wheel:
        {
            if ( state() != 0 )
                cmdList += Move;
            break;
        }
        case QEvent::KeyPress:
        {
            if ( eventPattern.keyMatch(
                QwtEventPattern::KeySelect1, (const QKeyEvent *)e) )
            {
                if ( state() == 0 )
                {
                    cmdList += Begin;
                    cmdList += Append;
                    cmdList += Append;
                    setState(1);
                }
                else
                {
                    cmdList += End;
                    setState(0);
                }
            }
            else if ( eventPattern.keyMatch(
                QwtEventPattern::KeySelect2, (const QKeyEvent *)e) )
            {
                if ( state() == 1 )
                    cmdList += Append;
            }
            break;
        }
        default:
            break;
    }

    return cmdList;
}
